package uk.ac.ebi.bioinvindex.search.hibernatesearch;

import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.hibernate.search.jpa.FullTextEntityManager;
import uk.ac.ebi.bioinvindex.model.impl.IdentifiableImpl;
import uk.ac.ebi.bioinvindex.search.FreeTextSearch;
import uk.ac.ebi.bioinvindex.search.SearchException;

import javax.persistence.EntityManager;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;




/**
 * User: Nataliya Sklyar (nsklyar@ebi.ac.uk)
 * Date: Sep 14, 2007
 */
public abstract class FreeTextSearchImpl<Target extends IdentifiableImpl>
	implements FreeTextSearch<Target>
{

	protected EntityManager entityManager;
	private Class<Target> targetClass;

	public List<Target> searchAllFields(String searchPattern) throws SearchException {
		List list;

		try {
			FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.createFullTextEntityManager(entityManager);

			QueryParser queryParser = new QueryParser("all", new StopAnalyzer());
			org.apache.lucene.search.Query luceneQuery = queryParser.parse(searchPattern);
			javax.persistence.Query fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, getTargetClass () );


			list = fullTextQuery.getResultList();
		} catch (ParseException e) {
			throw new SecurityException("Exception when parsing query " + searchPattern, e);
		}
		return list;
	}


	public Class<Target> getTargetClass() {
		if (targetClass == null) {
			Type type = ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments()[0];
			this.targetClass = ( Class<Target>) type;
		}
		return targetClass;
	}



	public EntityManager getEntityManager() {
		if (entityManager == null) {
			throw new IllegalStateException("EntityManager has not been set on StudyFreeTextSearchImpl before usage");
		}
		return entityManager;

	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
}
